package DRC;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.formula.functions.Cell;
import org.apache.poi.hssf.record.formula.functions.Row;
import org.apache.poi.hssf.usermodel.*;

import DRCOMM.DRHTTP_API;
import DRCOMM.DR_SESSION;
import DRCOMM.FJW_URI;
import DRCOMM.HttpRequestFormResolver;
import DRCOMM.dr_ajax_answer;
import DRCOMM.dr_util;
import DRCOMM.record_data_set;

public class dataItem4collect{

    public String uuid;
    public int channel_id=-1;
    public int dataItem_id=-1;
    public int slave_id=-1;
    public int register_type=-1;
    public int data_index=-1;
    public int address=-1;
    public String label="";
    public int data_type=-1;
    public float coefficient=-1;
    public int negation=-1;
    public int BCD=-1;
    public int ABS=-1;
    public float base_value=-1;
    public String introduction="";
    public String data_table="";
    public String field="";
    public float value=-1.0f;
    public Date timestamp=new Date();
    public Date create_time=new Date();

    public DRCDB drcdb;
    public static ArrayList<channel> channels=null;
    public static ArrayList<channel4collect> channels4collect=null;

    public dataItem4collect(DRCDB drcdb){
        this.drcdb=drcdb;
    }

    public dataItem4collect(DRCDB drcdb,int channel_id,int slave_id,int register_type,
        int data_index,int address,String label,int data_type){
        this.drcdb=drcdb;
        this.channel_id=channel_id;
        this.slave_id=slave_id;
        this.register_type=register_type;
        this.data_index=data_index;
        this.address=address;
        this.label=label;
        this.data_type=data_type;
    }

    public dataItem4collect(int channel_id,int dataItem_id,int slave_id,int register_type,
        int data_index,int address,String label,int data_type,float coefficient,int negation,
        int BCD,int ABS,float base_value,String introduction,String data_table,String field,
        float value,Date timestamp,Date create_time){
        // 唯一标识，用于测试用，判断dataItem4collect是否一致
        this.uuid=UUID.randomUUID().toString();
        this.channel_id=channel_id;
        this.dataItem_id=dataItem_id;
        this.slave_id=slave_id;
        this.register_type=register_type;
        this.data_index=data_index;
        this.address=address;
        this.label=label;
        this.data_type=data_type;
        this.coefficient=coefficient;
        this.negation=negation;
        this.BCD=BCD;
        this.ABS=ABS;
        this.base_value=base_value;
        this.introduction=introduction;
        this.data_table=data_table;
        this.field=field;
        this.value=value;
        this.timestamp=timestamp;
        this.create_time=create_time;
    }

    public void report(){
        //system.out.println("UUID="+this.uuid);
        //system.out.println("channel_id="+this.channel_id);
        //system.out.println("dataItem_id="+this.dataItem_id);
        //system.out.println("slave_id="+this.slave_id);
        //system.out.println("register_type="+this.register_type);
        //system.out.println("data_index="+this.data_index);
        //system.out.println("address="+this.address);
        //system.out.println("label="+this.label);
        //system.out.println("data_type="+this.data_type);
        //system.out.println("coefficient="+this.coefficient);
        //system.out.println("negation="+this.negation);
        //system.out.println("BCD="+this.BCD);
        //system.out.println("ABS="+this.ABS);
        //system.out.println("base_value="+this.base_value);
        //system.out.println("introduction="+this.introduction);
        //system.out.println("data_table="+this.data_table);
        //system.out.println("field="+this.field);
        //system.out.println("value="+this.value);
        //system.out.println("timestamp="+this.timestamp);
        //system.out.println("create_time="+this.create_time);
    }

    public void set_dataItem_id(int dataItem_id){
        this.dataItem_id=dataItem_id;
    }

    public record_data_set read_dataItems(int channel_id,int slave_id,int register_type,
        int start_address,int length){
        DRCDB db=this.drcdb;
        String sqlstr="select * from dataItem4collect ";
        sqlstr+=" where channel_id="+channel_id;
        sqlstr+=" and slave_id="+slave_id;
        sqlstr+=" and register_type="+register_type;
        sqlstr+=" and address>="+start_address;
        sqlstr+=" order by address";
        sqlstr+=" limit "+length;
        record_data_set rds=db.executeQuerySQL(sqlstr);
        sqlstr="select count(1) as ct from dataItem4collect ";
        sqlstr+=" where channel_id="+channel_id;
        sqlstr+=" and slave_id="+slave_id;
        sqlstr+=" and register_type="+register_type;
        sqlstr+=" and address>="+start_address;
        rds.count=db.get_query_count(sqlstr);
        return rds;
    }

    public static byte[] readLocalDataItem4bit(int channel_id,int slave_id,int register_type,
        int address,int data_count){
        List<Byte> result=new ArrayList<Byte>();
        ArrayList<Float> dis =new ArrayList<>();
        ArrayList<dataItem4collect> dataItems=null;
        for(channel4collect ch4c:channels4collect){
            if(channel_id==ch4c.channel_id){
                dataItems=ch4c.ds4c;
            }
        }
        if(dataItems==null)return null;
        // 逐个扫描数据点，判断slave_id,register_type,address是否一致
        for(dataItem4collect di:dataItems){
            if(slave_id==di.slave_id&&register_type==di.register_type&&address==di.address){
                for(int i=0;i<data_count&&i<dataItems.size();i++){
                    dis.add(dataItems.get(i).value);
                }
            }
        }
        byte b;
        for(int i=0;i<dis.size();i+=8){
            b=0;
            for(int j=i;j<(i+8)&&j<dis.size();j++){
                if(dis.get(j)==1.0){
                    b=(byte) ((byte)b|0x01<<(j-i));
                }
            }
            result.add(b);
        }
        // // 翻转result 列表
        // Collections.sort(result,Collections.reverseOrder());
        return dr_util.ListToBytes(result);
    }

    public static record_data_set readLocalDataItem(DRCDB drcdb,int channel_id,int slave_id,int register_type,
        int address,int data_count){
        String sqlstr="select protocol from channel4collect";
        sqlstr+=String.format(" where channel_id=%d" ,channel_id);
        record_data_set rds_channel4collect=drcdb.executeQuerySQL(sqlstr);
        if(rds_channel4collect.datas.size()>0){
            record_data_set rds;
            if(Integer.parseInt(rds_channel4collect.datas.get(0).get("protocol"))!=4){
                sqlstr="select value from dataItem4collect";
                sqlstr+=String.format(" where channel_id=%d and slave_id=%d" ,channel_id,slave_id);
                sqlstr+=String.format(" and register_type=%d" , register_type);
                sqlstr+=String.format(" and address>=%d" , address);
                sqlstr+=String.format(" order by address");
                sqlstr+=String.format(" limit 0,%d" , data_count);
                rds=drcdb.executeQuerySQL(sqlstr);
            }else{
                sqlstr="select value from dataItem4collect";
                sqlstr+=String.format(" where channel_id=%d" ,channel_id);
                sqlstr+=String.format(" and address>=%d" , address);
                sqlstr+=String.format(" order by address");
                sqlstr+=String.format(" limit 0,%d" , data_count);
                rds=drcdb.executeQuerySQL(sqlstr);
            }
            return rds;
        }else{
            return null;
        }
    }

    public static ArrayList<Float> readLocalDataItem(int channel_id,int slave_id,int register_type,
        int address,int data_count){
        ArrayList<Float> dis=new ArrayList<Float>();
        ArrayList<dataItem4collect> dataItems=null;
        for(channel4collect ch4c:channels4collect){
            if(channel_id==ch4c.channel_id){
                dataItems=ch4c.ds4c;
            }
        }
        if(dataItems==null)return null;
        // 逐个扫描数据点，判断slave_id,register_type,address是否一致
        for(dataItem4collect di:dataItems){
            if(slave_id==di.slave_id&&register_type==di.register_type&&address==di.address){
                for(int i=0;i<data_count&&i<dataItems.size();i++){
                    dis.add(dataItems.get(i).value);
                }
            }
        }
        return dis;
    }

    public static record_data_set readLocalDataItem2New(DRCDB drcdb,int channel_id,int address,int data_count){
        record_data_set rds = new record_data_set();
        int count = 0;
        List<String> columns = new ArrayList<>();
        List<Map<String,String>> datas = new ArrayList<>();
        columns.add("value");columns.add("dataItem_id");columns.add("timestamp");
        if (!channels4collect.isEmpty()){
            for (channel4collect ch4c: channels4collect){
                if (ch4c.channel_id == channel_id){
                    for (dataItem4collect di4c : ch4c.ds4c) {
                       if(di4c.address>=address && count<=data_count) {
                           count++;
                           Map<String,String> map = new HashMap<>();
                           map.put("value",String.valueOf(di4c.value));
                           map.put("dataItem_id",String.valueOf(di4c.dataItem_id));
                           map.put("timestamp",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(di4c.timestamp));
                           datas.add(map);
                       }
                    }
                }
            }
        }
        rds.datas = datas;
        rds.count = count;
        return rds;
    }

    public static record_data_set readLocalDataItem2(DRCDB drcdb,int channel_id,int address,int data_count){
        String sqlstr="select value,dataItem_id,timestamp from dataItem4collect";
        sqlstr+=String.format(" where channel_id=%d " ,channel_id);
                sqlstr+=String.format(" and address>=%d" , address);
                sqlstr+=String.format(" order by address");
                sqlstr+=String.format(" limit 0,%d" , data_count);
        record_data_set rds=drcdb.executeQuerySQL(sqlstr);
        if (!channels4collect.isEmpty()) {
            for (Map<String, String> d2c_data : rds.datas) {
                if (!d2c_data.get("dataItem_id").isEmpty()) {
                    for (channel4collect ch4c : channels4collect) {
                        if (ch4c.channel_id == channel_id){
                            for (dataItem4collect di4c : ch4c.ds4c) {
                                if (d2c_data.get("dataItem_id").equals(String.valueOf(di4c.dataItem_id))) {
                                    d2c_data.put("value", String.valueOf(di4c.value));
                                    d2c_data.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(di4c.timestamp));
                                }
                            }
                        }
                    }
                }
            }
        }
        return rds;
    }

    public static boolean updateLocalDataItem4bit(DRCDB drcdb,int channel_id,int slave_id,int register_type,
        int address,int value){
        boolean result=false;
        int bit_value=0;
        if(value==0xFF00)bit_value=1;
        Date now=new Date();
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sqlstr="update dataItem4collect";
        sqlstr+=String.format(" set timestamp='%s'" ,ft.format(now));
        sqlstr+=String.format(",value=%d" ,bit_value);
        sqlstr+=String.format(" where channel_id=%d and slave_id=%d" ,channel_id, slave_id);
        sqlstr+=String.format(" and register_type=%d" , register_type);
        sqlstr+=String.format(" and address=%d" , address);
        result=drcdb.executeUpdateSQL(sqlstr);
        return result;
    }

    /**
     * 更新采集通道数据点表
     * @param drcdb
     * @param channel_id
     * @param slave_id
     * @param register_type
     * @param address
     * @param value
     * @return
     */
    public static boolean updateLocalDataItem(DRCDB drcdb,int channel_id,int slave_id,int register_type,
        int address,float value){
        boolean result=false;
        Date now=new Date();
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
        String sqlstr="update dataItem4collect";
        sqlstr+=String.format(" set timestamp='%s'" ,ft.format(now));
        sqlstr+=String.format(",value=%f" ,value);
        // sqlstr+=String.format(" where channel_id=%d and slave_id=%d" ,channel_id, slave_id);
        // sqlstr+=String.format(" and register_type=%d" , register_type);
        // sqlstr+=String.format(" and address=%d" , address);
        sqlstr+=String.format(" where channel_id=%d " ,channel_id);
        sqlstr+=String.format(" and address=%d" , address);
        result=drcdb.executeUpdateSQL(sqlstr);
        return result;
    }

    /**
     * 更新采集通道数据点表
     * @param channel_id
     * @param slave_id
     * @param register_type
     * @param address
     * @param value
     * @return
     */
    public static boolean updateLocalDataItem(int channel_id,int slave_id,int register_type,
        int address,float value){
        boolean result=false;
        for(channel ch:channels){
            if(channel_id==ch.channel_id){
                for(dataItem4collect di:ch.c4c.ds4c){
                    if(di.slave_id==slave_id&&di.register_type==register_type&&di.address==address){
                        di.value=value;
                        di.timestamp=new Date();
                        result=true;
                    }
                }
            }
        }
        return result;
    }

    /**
     * 将数据写入采集通道数据点表
     * 包含新增数据点和更新数据点
     * 无数据点时新增，否则更新
     * @param drcdb
     * @param channel_id
     * @param slave_id
     * @param register_type
     * @param address
     * @param value
     * @return
     */
    public static boolean writeLocalDataItem(DRCDB drcdb,int channel_id,int slave_id,int register_type,
        int address,float value){
        boolean result=false;
        Date now=new Date();
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
        String sqlstr;
        sqlstr="select * from dataItem4collect";
        sqlstr+=String.format(" where channel_id=%d and address=%d",channel_id,address);
        if(address<4096){
            register_type=1;
        }else if(address<8192){
            register_type=2;
        }else if(address<12288){
            register_type=3;
        }else{
            register_type=4;
        }
        record_data_set rds=drcdb.executeQuerySQL(sqlstr);
        if(rds.datas.size()==0){
            sqlstr="insert into dataItem4collect(channel_id,slave_id,register_type,data_index,address,label,value,coefficient,timestamp,create_time)";
            sqlstr+=String.format(" values(%d,%d,%d,%d,%d,'data-%d-%d',%f,'%s','%s')", channel_id,slave_id,register_type,address,address,channel_id,address,value,1,ft.format(now),ft.format(now));
            drcdb.executeUpdateSQL(sqlstr);
        }else{
            result=dataItem4collect.updateLocalDataItem(drcdb,channel_id,slave_id,register_type,address,value);
        }
        return result;
    }

    /**
     * 将数据写入采集通道数据点表
     * 包含新增数据点和更新数据点
     * 无数据点时新增，否则更新
     * @param drcdb
     * @param channel_id
     * @param slave_id
     * @param register_type
     * @param address
     * @param value
     * @return
     */
    public static boolean writeLocalDataItem2(DRCDB drcdb,int channel_id,int slave_id,int register_type,
        int address,float value){
        boolean result=false;
        if(address<4096){
            register_type=1;
        }else if(address<8192){
            register_type=2;
        }else if(address<12288){
            register_type=3;
        }else{
            register_type=4;
        }
        for(channel4collect ch4c:channels4collect){
            if(channel_id==ch4c.channel_id){
                for(dataItem4collect d4c:ch4c.ds4c){
                    if(d4c.slave_id==slave_id&&d4c.register_type==register_type&&d4c.address==address){
                        d4c.value=value;
                        d4c.timestamp=new Date();
                        result=true;
                    }
                }
            }
        }
        if(!result){
            Date now=new Date();
            SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
            String sqlstr;
            sqlstr="insert into dataItem4collect(channel_id,slave_id,register_type,data_index,address,label,value,coefficient,timestamp,create_time)";
            sqlstr+=String.format(" values(%d,%d,%d,%d,%d,'data-%d-%d',%f,'%s','%s','%s')", channel_id,slave_id,register_type,address,address,channel_id,address,value,1,ft.format(now),ft.format(now));
            drcdb.executeUpdateSQL(sqlstr);
            sqlstr="select dataItem_id from dataItem4collect where channel_id="+channel_id;
            sqlstr+=" and slave_id="+slave_id;
            sqlstr+=" and register_type="+register_type;
            sqlstr+=" and address="+address;
            record_data_set rds=drcdb.executeQuerySQL(sqlstr);
            if(rds.datas.size()>0){
                int dataItem_id=Integer.parseInt(rds.datas.get(0).get("dataItem_id"));
                dataItem4collect d4c=new dataItem4collect(channel_id,dataItem_id,slave_id,register_type,
                    address,address,"",-1,-1,-1,-1,-1,0,"","","",value,now,now);
                    for(channel4collect ch4c:channels4collect){
                        if(channel_id==ch4c.channel_id){
                            ch4c.ds4c.add(d4c);
                        }
                    }
            }
        }
        return result;
    }

    // public record_data_set read_dataItems_page(int channel_id,int slave_id,int register_type,
    //     int pagesize,int page){
    //     DRCDB db=this.drcdb;
    //     String sqlstr="select * from dataItem4collect ";
    //     sqlstr+=" where channel_id="+channel_id;
    //     sqlstr+=" and slave_id="+slave_id;
    //     sqlstr+=" and register_type="+register_type;
    //     sqlstr+=" order by address";
    //     sqlstr+=String.format(" limit %d,%d",pagesize*(page-1),pagesize);
    //     record_data_set rds=db.executeQuerySQL(sqlstr);
    //     sqlstr="select count(1) as ct from dataItem4collect ";
    //     sqlstr+=" where channel_id="+channel_id;
    //     sqlstr+=" and slave_id="+slave_id;
    //     sqlstr+=" and register_type="+register_type;
    //     rds.count=db.get_query_count(sqlstr);
    //     return rds;
    // }

    public record_data_set read_dataItems_page(int channel_id,
        int pagesize,int page){
        DRCDB db=this.drcdb;
        // String sqlstr="select * from dataItem4collect ";
        // sqlstr+=" where channel_id="+channel_id;
        // sqlstr+=" order by address";
        // sqlstr+=String.format(" limit %d,%d",pagesize*(page-1),pagesize);
        // record_data_set rds=db.executeQuerySQL(sqlstr);
        // sqlstr="select count(1) as ct from dataItem4collect ";
        // sqlstr+=" where channel_id="+channel_id;
        // rds.count=db.get_query_count(sqlstr);
        channel4collect ch4c=null;
        for(int i=0;i<channels4collect.size();i++){
            if(channels4collect.get(i).channel_id==channel_id){
                ch4c=channels4collect.get(i);
                break;
            }
        }
        if(ch4c==null)return null;
        record_data_set rds=new record_data_set();
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
        List<String> columns=new ArrayList<String>();
        columns.add("channel_id");
        columns.add("dataItem_id");
        columns.add("slave_id");
        columns.add("register_type");
        columns.add("data_index");
        columns.add("address");
        columns.add("label");
        columns.add("data_type");
        columns.add("coefficient");
        columns.add("negation");
        columns.add("BCD");
        columns.add("ABS");
        columns.add("base_value");
        columns.add("introduction");
        columns.add("data_table");
        columns.add("field");
        columns.add("value");
        columns.add("timestamp");
        columns.add("create_time");
        rds.columns=columns;
        List<Map<String,String>> datas=new ArrayList<Map<String,String>>();
        dataItem4collect di4c;
        for(int i=0;i<ch4c.ds4c.size();i++){
            if (i >= (page-1) * pagesize && i < page*pagesize) {
                di4c=ch4c.ds4c.get(i);
                Map<String,String> row=new HashMap<String, String>();
                row.put("channel_id",""+di4c.channel_id);
                row.put("dataItem_id",""+di4c.dataItem_id);
                row.put("slave_id",""+di4c.slave_id);
                row.put("register_type",""+di4c.register_type);
                row.put("data_index",""+di4c.data_index);
                row.put("address",""+di4c.address);
                row.put("label",""+di4c.label);
                row.put("data_type",""+di4c.data_type);
                row.put("coefficient",""+di4c.coefficient);
                row.put("negation",""+di4c.negation);
                row.put("BCD",""+di4c.BCD);
                row.put("ABS",""+di4c.ABS);
                row.put("base_value",""+di4c.base_value);
                row.put("introduction",""+di4c.introduction);
                row.put("data_table",""+di4c.data_table);
                row.put("field",""+di4c.field);
                row.put("value",""+di4c.value);
                row.put("timestamp",""+ft.format(di4c.timestamp));
                row.put("create_time",""+ft.format(di4c.create_time));
                datas.add(row);
            }
        }
        rds.count=ch4c.ds4c.size();
        rds.datas=datas;
        return rds;
    }

    /**
     * 关联WEB API列表
     * @param api_lists
     * @param drcdb
     */
    public static void associate_actions(List<DRHTTP_API> api_lists,DRCDB drcdb) throws ClassNotFoundException{
        @SuppressWarnings("unchecked")
        Class<?> CLS=(Class<dataItem4collect>) Class.forName("DRC.dataItem4collect");
        for(Method method:CLS.getDeclaredMethods()){
            FJW_URI fjw_uri=method.getAnnotation(FJW_URI.class);
//            //system.out.println(method.toString());
            if(fjw_uri!=null){
//                //system.out.println(method.toString());
//                //system.out.println(fjw_uri.value());
                try {
                    api_lists.add((DRHTTP_API)method.invoke(CLS, drcdb, fjw_uri.value()));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @FJW_URI(value ="dataItem4collect/dataItemAllValue")
    public static DRHTTP_API dataItemAllValue(DRCDB drcdb,String URI) {
        return new DRHTTP_API(drcdb, URI) {
            @Override
            public String getResult(Map<String, Object> parameters, DR_SESSION drs) {
                List<Map<String, String>> data = new ArrayList<>();
                for (channel4collect channel4collect : channels4collect) {
                    if (channel4collect.channel_id == Integer.parseInt(this.get_parameters(parameters,"channel_id"))){
                        for (dataItem4collect dit4 : channel4collect.ds4c) {
                            Map<String,String> map = new HashMap<>();
                            map.put("id",String.valueOf(dit4.dataItem_id));
                            map.put("label",String.valueOf(dit4.label));
                            map.put("value",String.valueOf(dit4.value));
                            data.add(map);
                        }
                    }
                }
                record_data_set rds = new record_data_set();
                rds.datas = data;
                rds.count = data.size();
                List<String> list = new ArrayList<>();
                list.add("id");
                list.add("label");
                list.add("value");
                rds.columns = list;
                return record_data_set.get_answer_json_str(0,"",rds);
            }
        };
    }

    public static void writeData(List<String> firstList,List<List<String>> data,String channel_id){
        File dir  = new File("log/dataItem4");
        if (!dir.exists() || !dir.isDirectory()){
            boolean mkdir = dir.mkdir();
            if (!mkdir){
                System.out.println(dir.getAbsolutePath()+"目录创建失败");
            }
        }
        BufferedWriter writer = null;
        try {
            File file = new File("log/dataItem4/"+new SimpleDateFormat("yyyyMMdd").format(new Date())+"datItem4A"+channel_id+"A.txt");
            if (!file.exists()){
                boolean newFile = file.createNewFile();
                writer = new BufferedWriter(new FileWriter(file));
                String firstLine = String.join(",", firstList)+"\n";
                writer.write(firstLine);
            }else{
                writer = new BufferedWriter(new FileWriter(file,true));
            }
            // 追加数据

            for (List<String> datum : data) {
                boolean found = checkIfFileExistsAndContainsData("log/dataItem4/"+new SimpleDateFormat("yyyyMMdd").format(new Date())+"datItem4A"+channel_id+"A.txt", datum.get(datum.size()-1));
                if (!found) {
                    String joinData = String.join(",", datum) + "\n";
                    writer.write(joinData);
                }
            }
            System.out.println("数据已写入"+file.getAbsolutePath()+"文件。");
        } catch (IOException e) {
            try {
                if (writer != null)
                    writer.close();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }finally {
            try {
                if (writer != null)
                    writer.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 检查文件是否存在且包含指定的数据
     *
     * @param filePath 文件的路径
     * @param targetData 需要查找的数据
     * @return 如果文件存在且包含指定数据，则返回true；否则返回false
     */
    public static boolean checkIfFileExistsAndContainsData(String filePath, String targetData) {
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains(targetData)) {
                    return true; // 找到数据，返回true
                }
            }
        } catch (IOException e) {
            e.printStackTrace(); // 处理异常，这里只是简单地打印堆栈跟踪
            // 也可以根据需要返回false或抛出自定义异常
            return false;
        }
        return false; // 文件不存在或未找到数据
    }

    @FJW_URI(value ="dataItem4collect/dataItemList")
    public static DRHTTP_API dataItemList(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                //system.out.println("-------------------");
                for (channel4collect channel4collect : channels4collect) {
                    if (channel4collect.channel_id == Integer.parseInt(this.get_parameters(parameters,"channel_id"))){
                        //system.out.println(channel4collect.toString());
                        //system.out.println(channel4collect.ds4c);
                    }
                }
                String content="";
                String channel_id=this.get_parameters(parameters,"channel_id");
                String page=this.get_parameters(parameters,"page");
                String limit=this.get_parameters(parameters,"limit");
                dataItem4collect d4c=new dataItem4collect(drcdb);
                record_data_set rds=d4c.read_dataItems_page(
                    Integer.parseInt(channel_id),Integer.parseInt(limit),Integer.parseInt(page)
                    );
                content=record_data_set.get_answer_json_str(0,"",rds);
                return content;
            }
        };
    }

    @FJW_URI(value ="dataItem4collect/readDataItem")
    public static DRHTTP_API readDataItem(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                String content="";
                String dataItem_id=this.get_parameters(parameters,"dataItem_id");
                DRCDB db=drcdb;
                String sqlstr="select * from dataItem4collect ";
                sqlstr+=" where dataItem_id="+dataItem_id;
                record_data_set rds=db.executeQuerySQL(sqlstr);
                content=record_data_set.get_answer_json_str(0,"",rds);
                return content;
            }
        };
    }

    /**
     * 读取寄存器值，用于http调用
     * 以json格式返回，包括code和msg，以及数据结果
     * @param drcdb
     * @return
     */
    @FJW_URI(value ="dataItem4collect/readDataItem2json")
    public static DRHTTP_API readDataItem2json(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                String content="";
                String slave_id=this.get_parameters(parameters,"slave_id");
                String register_type=this.get_parameters(parameters,"register_type");
                String address=this.get_parameters(parameters,"address");
                DRCDB db=drcdb;
                String sqlstr="select * from dataItem4collect ";
                sqlstr+=" where slave_id="+slave_id;
                sqlstr+=" and register_type="+register_type;
                sqlstr+=" and address="+address;
                try {
                    record_data_set rds=db.executeQuerySQL(sqlstr);      
                    content=record_data_set.get_answer_json_str(0,"",rds);
                } catch (Exception e) {
                    content=dr_ajax_answer.sample_json_string(1,"error");
                }
                return content;
            }
        };
    }

    @FJW_URI(value ="dataItem4collect/checkDataItem")
    public static DRHTTP_API checkDataItem(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                String content="";
                String channel_id=this.get_parameters(parameters,"channel_id");
                String address=this.get_parameters(parameters,"address");
                String sqlstr;
                // 查询采集通道信息
                sqlstr="select address,count,protocol from channel4collect";
                sqlstr+=" where channel_id="+channel_id;
                record_data_set channel4collect_rds=drcdb.executeQuerySQL(sqlstr);
                if(channel4collect_rds.datas.size()>0){
                    int protocol=Integer.parseInt(channel4collect_rds.datas.get(0).get("protocol"));
                    //对MODBUS TCP/RTU Master可以检测是否越界
                    // 其他协议返回允许
                    if(protocol==6||protocol==7){
                        int address_start=Integer.parseInt(channel4collect_rds.datas.get(0).get("address"));
                        int address_count=Integer.parseInt(channel4collect_rds.datas.get(0).get("count"));
                        int check_address=Integer.parseInt(address);
                        if(check_address>=address_start&&check_address<(address_start+address_count)){
                            content=dr_ajax_answer.sample_json_string(0,"");
                        }else{
                            content=dr_ajax_answer.sample_json_string(1,"地址越界");
                        }
                    }else{
                        content=dr_ajax_answer.sample_json_string(0,"");
                    }
                }
                return content;
            }
        };
    }

    @FJW_URI(value ="dataItem4collect/saveDataItem")
    public static DRHTTP_API saveDataItem(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                String content="";
                String dataItem_id=this.get_parameters(parameters,"dataItem_id");
                String channel_id=this.get_parameters(parameters,"channel_id");
                String slave_id=this.get_parameters(parameters,"slave_id");
                String register_type=this.get_parameters(parameters,"register_type");
                String data_index=this.get_parameters(parameters,"data_index");
                String address=this.get_parameters(parameters,"address");
                String label=this.get_parameters(parameters,"label");
                String data_type=this.get_parameters(parameters,"data_type");
                String coefficient=this.get_parameters(parameters,"coefficient");
                String negation=this.get_parameters(parameters,"negation");
                String BCD=this.get_parameters(parameters,"BCD");
                String ABS=this.get_parameters(parameters,"ABS");
                String base_value=this.get_parameters(parameters,"base_value");
                String introduction=this.get_parameters(parameters,"introduction");
                String data_table=this.get_parameters(parameters,"data_table");
                String field=this.get_parameters(parameters,"field");
                String value=this.get_parameters(parameters,"value");
                DRCDB db=drcdb;
                String sqlstr;
                boolean result=false;
                negation=(negation.length()==0)?"0":"1";
                BCD=(BCD.length()==0)?"0":"1";
                ABS=(ABS.length()==0)?"0":"1";
                coefficient=(coefficient.length()==0)?"1":coefficient;
                base_value=(base_value.length()==0)?"0":base_value;
                sqlstr="select channel_id,slave_id,register_type from channel4collect";
                sqlstr+=String.format(" where channel_id=%s",channel_id);
                record_data_set channel4collect=db.executeQuerySQL(sqlstr);
                SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if(channel4collect.datas.size()>0){
                    slave_id=channel4collect.datas.get(0).get("slave_id");
                    register_type=channel4collect.datas.get(0).get("register_type");
                }
                if(dataItem_id==null||dataItem_id=="") {
                    Date now = new Date();
                    sqlstr = "insert into dataItem4collect(channel_id,slave_id,register_type,data_index,address,label,data_type,coefficient,negation,BCD,ABS,base_value,introduction,data_table,field,value,create_time) ";
                    sqlstr += String.format(" values(%s,%s,%s,%s,%s,'%s',%s,%s,%s,%s,%s,%s,'%s','%s','%s',%s,'%s')",
                            channel_id, slave_id, register_type, data_index, address, label, data_type,
                            coefficient, negation, BCD, ABS, base_value, introduction, data_table, field, value, ft.format(now));
                    result = db.executeUpdateSQL(sqlstr);
                    sqlstr = "select channel_id,name,dataitem_type,host_ip,port,protocol,path,filename,com,band_rate,parity,stop,enable,slave_id,register_type,address,count,run_cycle,create_time,creat_text from channel4collect";
                    sqlstr += String.format(" where channel_id='%s'",channel_id);
                    record_data_set rds = drcdb.executeQuerySQL(sqlstr);
                    if (!rds.datas.isEmpty()) {
                        for (channel4collect ch4c : channels4collect) {
                            if (ch4c.channel_id == Integer.parseInt(channel_id)){
                                String sqlstr_d4c="select * from dataItem4collect ";
                                sqlstr_d4c+=" where channel_id="+channel_id;
                                sqlstr_d4c+=" order by dataItem_id";
                                record_data_set rds_d4c=drcdb.executeQuerySQL(sqlstr_d4c);
                                Date create_time = new Date();
                                try {
                                    create_time = ft.parse(rds.datas.get(0).get("create_time"));
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                }
                                ch4c.ds4c.add(new dataItem4collect(Integer.parseInt(channel_id),Integer.parseInt(rds_d4c.datas.get(0).get("dataItem_id")),Integer.parseInt(slave_id),Integer.parseInt(register_type),Integer.parseInt(data_index),
                                        Integer.parseInt(address),label,Integer.parseInt(data_type),Float.parseFloat(coefficient),Integer.parseInt(negation),
                                        Integer.parseInt(BCD),Integer.parseInt(ABS),Float.parseFloat(base_value),introduction,data_table,field,Float.parseFloat(value),
                                        new Date(),create_time));
                            }
                        }
                    }
                }else{
                    sqlstr="update dataItem4collect";
                    sqlstr+=String.format(" set channel_id=%s" , channel_id);
                    sqlstr+=String.format(",slave_id=%s" , slave_id);
                    sqlstr+=String.format(",register_type=%s" , register_type);
                    sqlstr+=String.format(",data_index=%s" , data_index);
                    sqlstr+=String.format(",address=%s" , address);
                    sqlstr+=String.format(",label='%s'" , label);
                    sqlstr+=String.format(",data_type=%s" , data_type);
                    sqlstr+=String.format(",coefficient=%s" , coefficient);
                    sqlstr+=String.format(",negation=%s" , negation);
                    sqlstr+=String.format(",BCD=%s" , BCD);
                    sqlstr+=String.format(",ABS=%s" , ABS);
                    sqlstr+=String.format(",base_value=%s" , base_value);
                    sqlstr+=String.format(",introduction='%s'" , introduction);
                    sqlstr+=String.format(",data_table='%s'" , data_table);
                    sqlstr+=String.format(",field='%s'" , field);
                    sqlstr+=String.format(",value=%s" , value);
                    sqlstr+=String.format(" where dataItem_id=%s" , dataItem_id);
                    result=db.executeUpdateSQL(sqlstr);

                    sqlstr = "select channel_id,name,dataitem_type,host_ip,port,protocol,path,filename,com,band_rate,parity,stop,enable,slave_id,register_type,address,count,run_cycle,create_time,creat_text from channel4collect";
                    sqlstr += String.format(" where channel_id='%s'",channel_id);
                    record_data_set rds = drcdb.executeQuerySQL(sqlstr);
                    if (!rds.datas.isEmpty()) {
                        for (channel4collect ch4c : channels4collect) {
                            if (ch4c.channel_id == Integer.parseInt(channel_id)){
                                for (dataItem4collect di4c : ch4c.ds4c) {
                                    if (di4c.dataItem_id == Integer.parseInt(dataItem_id)){
                                        di4c.slave_id = Integer.parseInt(slave_id);
                                        di4c.register_type = Integer.parseInt(register_type);
                                        di4c.data_index = Integer.parseInt(data_index);
                                        di4c.address = Integer.parseInt(address);
                                        di4c.label = label;
                                        di4c.data_type = Integer.parseInt(data_type);
                                        di4c.coefficient = Float.parseFloat(coefficient);
                                        di4c.negation = Integer.parseInt(negation);
                                        di4c.BCD = Integer.parseInt(BCD);
                                        di4c.ABS = Integer.parseInt(ABS);
                                        di4c.base_value = Float.parseFloat(base_value);
                                        di4c.introduction = introduction;
                                        di4c.data_table = data_table;
                                        di4c.field = field;
                                        di4c.value = Float.parseFloat(value);
                                    }
                                }
                            }
                        }
                    }
                }
                if(result){
                    content=dr_ajax_answer.sample_json_string(0,"");
                }else{
                    content=dr_ajax_answer.sample_json_string(1,"保存失败！");
                }
                return content;
            }
        };
    }

    @FJW_URI(value ="dataItem4collect/delDataItem")
    public static DRHTTP_API delDataItem(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                String content="";
                String dataItem_id=this.get_parameters(parameters,"dataItem_id");
                boolean result=false;
                DRCDB db=drcdb;
                String sqlstr;
                sqlstr="delete from dataItem4collect";
                sqlstr+=String.format(" where dataItem_id=%s" , dataItem_id);
                result=db.executeUpdateSQL(sqlstr);
                if(result){
                    content=dr_ajax_answer.sample_json_string(0,"");
                }else{
                    content=dr_ajax_answer.sample_json_string(1,"保存失败！");
                }
                for (channel4collect ch4c : channels4collect) {
                    for (dataItem4collect di4c : ch4c.ds4c) {
                        if (di4c.dataItem_id == Integer.parseInt(dataItem_id)){
                            ch4c.ds4c.remove(di4c);
                        }
                    }
                }
                return content;
            }
        };
    }

    @FJW_URI(value ="dataItem4collect/upload_dataItem_table")
    public static DRHTTP_API upload_dataItem_table(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                String content="";
                Object upload_file=this.get_parameterItem(this.parameters,"upload_file");
                String channel_id=((DRCOMM.HttpRequestFormResolver.ParamItem)(this.get_parameterItem(this.parameters,"channel_id"))).getVal();
                boolean result=false;
                int cell_process_index=0;
                if(upload_file!=null){
                    InputStream fis = null;
                    try {
                        HttpRequestFormResolver.ParamItem pi=(HttpRequestFormResolver.ParamItem)upload_file;          
//                        //system.out.println(pi.getFilename());
                        File excel_file=new File("./upload/"+pi.getFilename());
                        fis=new FileInputStream(excel_file.getAbsolutePath());
                        HSSFWorkbook wb=new HSSFWorkbook(fis,true);

                        HSSFSheet ws=wb.getSheetAt(0);
                        HSSFRow row;
                        HSSFCell cell;
                        int cell_channel_id,cell_dataItem_data_index,cell_dataItem_address;
                        int cell_data_type_id,negation,BCD,ABS;
                        float coefficient,base_value,value;
                        HSSFRichTextString cell_label,cell_data_type;
                        int max_data_count=10000;
                        cell_channel_id=Integer.parseInt(channel_id);
                        try {
                            result=true;
                            for(int i=1;i<max_data_count;i++){
                                row=ws.getRow(i);
                                cell=row.getCell(1);
                                cell_label=cell.getRichStringCellValue();
                                cell=row.getCell(2);
                                cell_dataItem_data_index=(int)cell.getNumericCellValue();
                                cell=row.getCell(3);
                                cell_dataItem_address=(int)cell.getNumericCellValue();
                                cell=row.getCell(4);
                                cell_data_type=cell.getRichStringCellValue();
                                cell_data_type_id=Integer.parseInt(cell_data_type.toString().substring(0, 1));
                                cell=row.getCell(5);
                                coefficient=(float)cell.getNumericCellValue();
                                cell=row.getCell(6);
                                negation=(int)cell.getNumericCellValue();
                                cell=row.getCell(7);
                                BCD=(int)cell.getNumericCellValue();
                                cell=row.getCell(8);
                                ABS=(int)cell.getNumericCellValue();
                                cell=row.getCell(9);
                                base_value=(float)cell.getNumericCellValue();
                                cell=row.getCell(10);
                                value=(float)cell.getNumericCellValue();
                                if(saveDataItem2(drcdb,channel_id,
                                    cell_label.toString(),
                                    cell_dataItem_data_index+"",
                                    cell_dataItem_address+"",
                                    cell_data_type_id+"",
                                    coefficient+"",
                                    negation+"",
                                    BCD+"",ABS+"",base_value+"",
                                    value+""
                                    )){
                                    cell_process_index++;
                                }
                                //system.out.println(String.format("channel_id=%s,label=%s,dataItem_id=%d",
//                                    cell_channel_id,cell_label.getString(),cell_dataItem_address
//                                ));
                            }
                            
                        } catch (Exception e) {
                            //system.out.println("excel read finished!");
                        }
                        fis.close();
                    } catch (Exception e) {
                        //system.out.println(e.getLocalizedMessage());
                    }
                }
                content=dr_ajax_answer.sample_json_string(0,"");
                if(result){
                    content=dr_ajax_answer.sample_json_string(0,String.format("点表读取成功，保存数据[%d]条", cell_process_index));
                }else{
                    content=dr_ajax_answer.sample_json_string(1,"上传失败！");
                }
                return content;
            }
        };
    }

    public static boolean saveDataItem2(DRCDB drcdb,
        String channel_id,String label,
        String data_index,String address,String data_type,
        String coefficient,String negation,String BCD,String ABS,
        String base_value,String value) {
        DRCDB db=drcdb;
        String sqlstr;
        boolean result=false;
        String slave_id="";
        String register_type="";
        String dataItem_id;
        sqlstr="select channel_id,slave_id,register_type from channel4collect";
        sqlstr+=String.format(" where channel_id=%s",channel_id);
        record_data_set channel4collect=db.executeQuerySQL(sqlstr);
        if(channel4collect.datas.size()>0){
            slave_id=channel4collect.datas.get(0).get("slave_id");
            register_type=channel4collect.datas.get(0).get("register_type");
        }
        record_data_set ds;
        sqlstr="select dataItem_id from dataItem4collect ";
        sqlstr+=String.format("where channel_id=%s ", channel_id);
        sqlstr+=String.format("and address=%s limit 0,1", address);
        ds=drcdb.executeQuerySQL(sqlstr);
        if(ds.count==0){
            Date now=new Date();
            SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
            sqlstr="insert into dataItem4collect(channel_id,slave_id,register_type,data_index,address,label,data_type,coefficient,negation,BCD,ABS,base_value,value,create_time) ";
            sqlstr+=String.format(" values(%s,%s,%s,%s,%s,'%s',%s,%s,%s,%s,%s,%s,%s,'%s')",
                channel_id,slave_id,register_type,data_index,address,label,data_type,
                coefficient,negation,BCD,ABS,base_value,value,ft.format(now));
        }else{
            dataItem_id=ds.datas.get(0).get("dataItem_id");
            sqlstr="update dataItem4collect";
            sqlstr+=String.format(" set channel_id=%s" , channel_id);
            sqlstr+=String.format(",slave_id=%s" , slave_id);
            sqlstr+=String.format(",register_type=%s" , register_type);
            sqlstr+=String.format(",data_index=%s" , data_index);
            sqlstr+=String.format(",address=%s" , address);
            sqlstr+=String.format(",label='%s'" , label);
            sqlstr+=String.format(",data_type=%s" , data_type);
            sqlstr+=String.format(",coefficient=%s" , coefficient);
            sqlstr+=String.format(",negation=%s" , negation);
            sqlstr+=String.format(",BCD=%s" , BCD);
            sqlstr+=String.format(",ABS=%s" , ABS);
            sqlstr+=String.format(",base_value=%s" , base_value);
            sqlstr+=String.format(",value=%s" , value);
            sqlstr+=String.format(" where dataItem_id=%s" , dataItem_id);
        }
        result=db.executeUpdateSQL(sqlstr);
        return result;
    }

    /**
     * 设定寄存器值，用于通过http调用
     * 返回值为json格式结果，包括code和msg
     * @return
     */
    @FJW_URI(value ="dataItem4collect/setDataItem")
    public static DRHTTP_API setDataItem(DRCDB drcdb,String URI){
        return new DRHTTP_API(drcdb,URI){
            @Override
            public String getResult(Map<String, Object> parameters,DR_SESSION drs){
                String content="";
                String slave_id=this.get_parameters(parameters,"slave_id");
                String register_type=this.get_parameters(parameters,"register_type");
                String address=this.get_parameters(parameters,"address");
                String value=this.get_parameters(parameters,"value");
                String sqlstr="update dataItem4collect";
                sqlstr+=String.format(" set value=%s" , value);
                sqlstr+=String.format(" where slave_id=%s" , slave_id);
                sqlstr+=String.format(" and register_type=%s" , register_type);
                sqlstr+=String.format(" and address=%s" , address);
                boolean result=drcdb.executeUpdateSQL(sqlstr);
                if(result){
                    content=dr_ajax_answer.sample_json_string(0,"");
                }else{
                    content=dr_ajax_answer.sample_json_string(1,"保存失败！");
                }
                return content;
            }
        };
    }

    public static void main(String[] args){
        List<String> fie = Arrays.asList("apple", "banana", "cherry");
        List<String> data = new ArrayList<>();
        List<List<String>> data2 = new ArrayList<>();
        data.add("4");
        data.add("23");
        data.add("892");
        data2.add(data);
        writeData(fie,data2,"4");
        DRCDB drcdb=new DRCDB();
        // dataItem4collect d4c=new dataItem4collect(drcdb);
        // record_data_set rds=d4c.read_dataItem4collects_page(1,1,3,10,1);
        // // for(Map<String, String> row:rds.datas){
        // //     //system.out.println(row.get("dataItem4collect"));
        // // }
        // //system.out.println(record_data_set.get_answer_json_str(0,"",rds));
//        byte[] result=dataItem4collect.readLocalDataItem4bit(drcdb,1,1, 1, 0, 20);
        //system.out.println(dr_util.bytes2hexstr(result));

    }
}